//
//  XUSBManager.h
//  TestDemo
//
//  Created by Apple Mac mini intel on 2024/8/14.
//

#import <Foundation/Foundation.h>
#import <IOKit/usb/IOUSBLib.h>

typedef NS_ENUM(NSInteger, USBConnectionError) {
    USBConnectionErrorMasterPortCreationFailed = 1,          ///< dealWithMasterPort
    USBConnectionErrorMatchingDictionaryCreationFailed,      ///< dealWithMatchingDictionary
    USBConnectionErrorVendorIDCreationFailed,                ///< dealWithVendorID
    USBConnectionErrorProductIDCreationFailed,               ///< dealWithProductID
    USBConnectionErrorDevicePluginCreationFailed,            ///< dealWithDevice
    USBConnectionErrorDeviceInterfaceCreationFailed,         ///< dealWithDevice
    USBConnectionErrorDeviceOpenFailed,                      ///< dealWithDevice
    USBConnectionErrorConfigurationCountFailed,              ///< dealWithDevice
    USBConnectionErrorConfigDescriptorFailed,                ///< dealWithDevice
    USBConnectionErrorSetConfigurationFailed,                ///< dealWithDevice
    USBConnectionErrorInterfaceIteratorCreationFailed,       ///< dealWithDevice
    USBConnectionErrorInterfacePluginCreationFailed,         ///< dealWithInterface
    USBConnectionErrorInterfaceCreationFailed,               ///< dealWithInterface
    USBConnectionErrorInterfaceOpenFailed,                   ///< dealWithInterface
    USBConnectionErrorEndpointCountFailed,                   ///< dealWithInterface
    USBConnectionErrorSetAlternateInterfaceFailed,           ///< dealWithInterface
    USBConnectionErrorEndpointCountAltSettingFailed,         ///< dealWithInterface
    USBConnectionErrorPipePropertiesFailed,                  ///< dealWithPipes
    USBConnectionErrorDeviceRemoved,                         ///< dealWithDeviceRemoved
    USBConnectionErrorNormalDisconnection,                   ///< normal disconnection
    USBConnectionErrorNotFoundDevice,                        ///< not found device
    USBConnectionErrorOtherDisconnection,                    ///< error disconnection
};


@class XUSBManager;
@class XUSBDeviceInfo;
@protocol XUSBManagerDelegate <NSObject>
@optional

/// Callback for successful connection
/// @param device device value
- (void)xUSBConnected:(XUSBDeviceInfo *)device;

/// Callback for disconnection error
/// @param code Error code
/// @param message error message
/// @param device device value
- (void)xUSBDisconnectWithError:(int)code message:(NSString *)message device:(XUSBDeviceInfo *)device;

/// Callback for successful data transmission
/// @param device device value
- (void)xUSBWriteValueWithDevice:(XUSBDeviceInfo *)device isSuccess:(BOOL)isSuccess message:(NSString *)message;

/// Callback for receiving data from the printer
/// @param data Received data
/// @param device device info
- (void)xUSBReceiveValueForData:(NSData *)data device:(XUSBDeviceInfo *)device;

/// Callback for USB device search results
/// @param state  state == 0: outline, state == 1: online
/// @param device device info
- (void)xUSBDidSearch:(int)state device:(XUSBDeviceInfo *)device;

@end

/// Class representing USB device information
@interface XUSBDeviceInfo : NSObject

/// Vendor ID of the USB device
@property (nonatomic, assign) uint16_t vid;

/// Product ID of the USB device
@property (nonatomic, assign) uint16_t pid;

/// Location ID of the USB device
@property (nonatomic, strong) NSString *locationId;

/// Name of the USB device
@property (nonatomic, strong) NSString *deviceName;

/// USB interface for the device
@property (nonatomic, assign) IOUSBInterfaceInterface245 **interface;

/// USB device interface
@property (nonatomic, assign) IOUSBDeviceInterface245 **dev;

/// Input pipe for data transfer
@property (nonatomic, assign) UInt8 pipeIn;

/// Output pipe for data transfer
@property (nonatomic, assign) UInt8 pipeOut;

@end

/// Block type for handling USB device search results
typedef void(^UsbDidSearch)(XUSBDeviceInfo *usbDevice, int state); // state == 0: outline, state == 1: online

/// Callback block type definition for reporting POS printer status.
typedef void (^XUSBPOSPrinterStatusBlock)(NSData *status);

/// Callback block type definition for reporting label printer status.
typedef void (^XUSBLabelPrinterStatusBlock)(NSData *status);

/// Callback block type definition for reporting printer serial number.
typedef void (^XUSBPrinterSNBlock)(NSString *sn);

/// Callback block type definition for reporting cash box status.
typedef void (^XUSBCashBoxBlock)(NSData *status);

/// Class responsible for managing USB devices
@interface XUSBManager : NSObject

/// Singleton instance of XUSBManager
+ (instancetype)sharedInstance;

/// Block to handle search results
@property (nonatomic, copy) UsbDidSearch searchBlock;

@property (nonatomic, weak) id<XUSBManagerDelegate> delegate;

/// The callback block called when reporting POS printer status.
@property (nonatomic, copy) XUSBPOSPrinterStatusBlock statusPOSBlock;

/// The callback block called when reporting label printer status.
@property (nonatomic, copy) XUSBLabelPrinterStatusBlock statusLabelBlock;

/// The callback block called when reporting printer serial number.
@property (nonatomic, copy) XUSBPrinterSNBlock snBlock;

/// The callback block called when reporting cash box status.
@property (nonatomic, copy) XUSBCashBoxBlock cashBoxBlock;

/// Remove a delegate object
/// @param delegate Delegate object
- (void)removeDelegate:(id<XUSBManagerDelegate>) delegate;

/// Remove all delegate objects
- (void)removeAllDelegates;

/// Connect to a specified USB device object
- (void)connectDevice:(XUSBDeviceInfo *)device;

/// Connect USB device with name
- (void)connectDeviceName:(NSString *)deviceName;

/// send Data
- (void)sendData:(NSData *)data;

/// Listen for USB search events
- (void)listenUsbSearchEvent:(UsbDidSearch)searchResult;

/// Disconnect a specified USB device
- (IOReturn)disconnect;

/// Search devices
- (NSArray<XUSBDeviceInfo *> *)searchDevices;

/// Printer Status (for receipt printer)
/// @param statusBlock The status callback
- (void)printerPOSStatus:(XUSBPOSPrinterStatusBlock)statusBlock;

/// Printer Status (for label printer)
/// @param statusBlock The status callback
- (void)printerLabelStatus:(XUSBLabelPrinterStatusBlock)statusBlock;

/// Printer Serial Number
/// @param snBlock The serial number callback
- (void)printerSN:(XUSBPrinterSNBlock)snBlock;

/// Cash Box Status
/// @param cashBoxBlock The status callback
- (void)cashBoxCheck:(XUSBCashBoxBlock)cashBoxBlock;

@end


